/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.transas.zorlog.ui.graph;

import com.transas.zorlog.data.DataSource;
import com.transas.zorlog.data.log.Config;
import java.awt.Color;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


/**
 *
 * @author amalikov
 */
public class GraphPaneConfig {

	public void open(String path, DataSource dataSource) {
		paneList.clear();
        try (Reader file = new FileReader(path)) {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(file));

			NodeList panes = doc.getDocumentElement().getElementsByTagName("pane");
			for (int i = 0; i < panes.getLength(); ++i)
				createPane((Element)panes.item(i), dataSource);
        } catch (IOException | SAXException | ParserConfigurationException ex) {
            Logger.getLogger(GraphPaneConfig.class.getName()).log(Level.SEVERE, null, ex);
        }
	}

	public void save(String path) {
		try (Writer file = new OutputStreamWriter(new FileOutputStream(path, false), "UTF-8")) {
			StreamResult streamResult = new StreamResult(file);
			TransformerFactory tf = TransformerFactory.newInstance();
			tf.setAttribute("indent-number", 4); 
			Transformer serializer = tf.newTransformer();
			serializer.setOutputProperty(OutputKeys.METHOD, "xml");
			serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			serializer.setOutputProperty(OutputKeys.INDENT, "yes");
			serializer.transform(createDOMSource(), streamResult);
        } catch (IOException | TransformerException | ParserConfigurationException ex) {
			Logger.getLogger(Config.class.getName()).log(Level.SEVERE, null, ex);
		}
	}
	
	private DOMSource createDOMSource() throws ParserConfigurationException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		DOMImplementation impl = db.getDOMImplementation();
		Document doc = impl.createDocument(null, "preset", null);
		doc.setXmlStandalone(true);
		Element root = doc.getDocumentElement();
			
		for (GraphPane gp : paneList) {
			Element pane_node = doc.createElementNS(null, "pane");
			List<Graph> graphs = gp.getGraphs();
				
			for (Graph graph : graphs) {
				Element graph_node = doc.createElementNS(null, "graph");
				graph_node.setAttribute("name", graph.getName());
				final String color = "0x" + Integer.toHexString(graph.getColor().getRGB() | 0xFF000000).substring(2);
				graph_node.setAttribute("color", color);
				pane_node.appendChild(graph_node);
			}
					
			root.appendChild(pane_node);
		}
		
		return new DOMSource(doc);
	}
	
	
	public GraphPane addPane() {
		final GraphPane gp = new GraphPane();
		paneList.add(gp);
		gp.setBackground(Color.WHITE);
		gp.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		return gp;
	}
	
	public void deletePane(GraphPane pane) {
		paneList.remove(pane);
	}
	
	public List<GraphPane> getPaneList() {
		return paneList;
	}

	private void createPane(Element paneNode, DataSource dataSource) {
		final GraphPane gp = addPane();
		NodeList graphs = paneNode.getElementsByTagName("graph");
		for (int i = 0; i < graphs.getLength(); ++i)
			createGraph((Element)graphs.item(i), gp, dataSource);
	}	

	private void createGraph(Element graphNode, GraphPane gp, DataSource dataSource) {
		NamedNodeMap graphAttrs = graphNode.getAttributes();
		Node nameNode = graphAttrs.getNamedItem("name");
		if (nameNode != null) {
			String graphName = nameNode.getNodeValue();
			Node colorNode = graphAttrs.getNamedItem("color");
			if (colorNode != null)
				gp.addGraph(dataSource, graphName, Color.decode(colorNode.getNodeValue()));
			else
				gp.addGraph(dataSource, graphName);
		}
	}
	
	private List<GraphPane> paneList = new ArrayList<>();
}
